package imp

import (
	sqlc "bgs/db/sqlc"
	storeSpokesmanGrpc "bgs/grpc/gen/service/store_spokesman"
	"bgs/grpc/gen/shared/message"
	"context"
	"fmt"
)

/****************************************************************************************/
/*                               store_spokesman entity of helper                       */
/****************************************************************************************/

func transformStoreSpokesmanEntityToPb(o sqlc.Spokesman) *storeSpokesmanGrpc.StoreSpokesmanEntity {
	return &storeSpokesmanGrpc.StoreSpokesmanEntity{
		Id:                   o.ID,
		UserId:               o.UserID,
		StoreId:              o.StoreID.Int64,
		AliasName:            o.AliasName,
		Became:               sqlc.GoTimeToPBTimestamp(o.Became),
		Remark:               o.Remark.String,
		EndorseActivityCount: o.EndorseActivityCount,
		SaleAmount:           o.SaleAmount,
	}
}

func mapStoreSpokesmanEntityToPb(list []sqlc.Spokesman, f func(sqlc.Spokesman) *storeSpokesmanGrpc.StoreSpokesmanEntity) []*storeSpokesmanGrpc.StoreSpokesmanEntity {
	r := make([]*storeSpokesmanGrpc.StoreSpokesmanEntity, len(list))
	for i, item := range list {
		r[i] = f(item)
	}
	return r
}

/****************************************************************************************/
/*                               store_spokesman entity of cmd                          */
/****************************************************************************************/

// UpdateStoreSpokesman 更新门店代言人
func (s *StoreAPIService) UpdateStoreSpokesman(ctx context.Context, req *storeSpokesmanGrpc.UpdateStoreSpokesmanRequest) (res *storeSpokesmanGrpc.UpdateStoreSpokesmanResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("store_spokesmanImp->UpdateStoreSpokesman:%v", req)
	res = &storeSpokesmanGrpc.UpdateStoreSpokesmanResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	StoreSpokesman, err := s.dao.Q.UpdateSpokesman(ctx, sqlc.UpdateSpokesmanParams{
		ID:        req.Id,
		AliasName: req.AliasName,
		Remark:    sqlc.NSFromString(req.Remark),
	})
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.StoreSpokesman = transformStoreSpokesmanEntityToPb(StoreSpokesman)
	return
}

/****************************************************************************************/
/*                            store_spokesman entity of query                           */
/****************************************************************************************/

// GetStoreSpokesman 获取单个门店代言人
func (s *StoreAPIService) GetStoreSpokesman(ctx context.Context, req *storeSpokesmanGrpc.GetStoreSpokesmanRequest) (res *storeSpokesmanGrpc.GetStoreSpokesmanResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("store_spokesmanImp->GetStoreSpokesman:%v", req)
	res = &storeSpokesmanGrpc.GetStoreSpokesmanResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	brandSpokesman, err := s.dao.Q.GetSpokesman(ctx, req.Id)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.StoreSpokesman = transformStoreSpokesmanEntityToPb(brandSpokesman)
	return
}

// ListNormalStoreSpokesmansByStoreID  获取正常的门店代言人列表
func (s *StoreAPIService) ListNormalStoreSpokesmansByStoreID(ctx context.Context, req *storeSpokesmanGrpc.ListNormalStoreSpokesmansByStoreIDRequest) (res *storeSpokesmanGrpc.ListNormalStoreSpokesmansByStoreIDResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("store_spokesmanImp->ListNormalStoreSpokesmansByStoreID:%v", req)
	res = &storeSpokesmanGrpc.ListNormalStoreSpokesmansByStoreIDResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	q := s.dao.Q
	storeID := req.StoreId
	total, err := q.CountNormalStoreSpokesmansByStoreID(ctx, sqlc.NInt64FromInt64(storeID))
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	if total == 0 {
		// 不用继续调用listfunc
		return
	}
	storeSpokesmans, err := q.ListNormalStoreSpokesmansByStoreID(ctx, sqlc.ListNormalStoreSpokesmansByStoreIDParams{
		Limit:   req.Limit,
		Offset:  req.Offset,
		StoreID: sqlc.NInt64FromInt64(storeID),
	})
	if err != nil {
		return
	}
	res.Total = total
	res.StoreSpokesmans = mapStoreSpokesmanEntityToPb(storeSpokesmans, transformStoreSpokesmanEntityToPb)
	return
}

/****************************************************************************************/
/*                            store_spokesmanJoins entity of helper                     */
/****************************************************************************************/

func transformStoreSpokesmanWithStoreEntityToPb(row sqlc.ListNormalStoreSpokesmanWithStoresByUserIDRow) *storeSpokesmanGrpc.StoreSpokesmanWithStoreEntity {
	return &storeSpokesmanGrpc.StoreSpokesmanWithStoreEntity{
		Id:        row.ID,
		UserId:    row.UserID,
		StoreId:   row.StoreID.Int64,
		AliasName: row.AliasName,
		Became:    sqlc.GoTimeToPBTimestamp(row.Became),
		Remark:    row.Remark.String,
		// store
		StoreName:                 row.StoreName,
		StorePic:                  row.StorePic.String,
		StoreFansCount:            row.FansCount,
		StorePublishActivityCount: row.PublishActivityCount,
	}
}

func mapStoreSpokesmanWithStoreEntityToPb(list []sqlc.ListNormalStoreSpokesmanWithStoresByUserIDRow, f func(sqlc.ListNormalStoreSpokesmanWithStoresByUserIDRow) *storeSpokesmanGrpc.StoreSpokesmanWithStoreEntity) []*storeSpokesmanGrpc.StoreSpokesmanWithStoreEntity {
	r := make([]*storeSpokesmanGrpc.StoreSpokesmanWithStoreEntity, len(list))
	for i, item := range list {
		r[i] = f(item)
	}
	return r
}

func transformStoreSpokesmanWithUserEntityToPb(row sqlc.ListNormalStoreSpokesmanWithUsersByStoreIDRow) *storeSpokesmanGrpc.StoreSpokesmanWithUserEntity {
	return &storeSpokesmanGrpc.StoreSpokesmanWithUserEntity{
		// brand_admin
		Id:                   row.ID,
		UserId:               row.UserID,
		StoreId:              row.StoreID.Int64,
		AliasName:            row.AliasName,
		Became:               sqlc.GoTimeToPBTimestamp(row.Became),
		Remark:               row.Remark.String,
		EndorseActivityCount: row.EndorseActivityCount,
		SaleAmount:           row.SaleAmountCalculated, // 目前使用实时计算的
		// user
		SpokesmanUserNickName: row.SpokesmanUserNickName,
		SpokesmanUserPic:      row.SpokesmanUserPic,
		// stat
		FansCount: row.FansCount,
	}
}

func mapStoreSpokesmanWithUserEntityToPb(list []sqlc.ListNormalStoreSpokesmanWithUsersByStoreIDRow, f func(sqlc.ListNormalStoreSpokesmanWithUsersByStoreIDRow) *storeSpokesmanGrpc.StoreSpokesmanWithUserEntity) []*storeSpokesmanGrpc.StoreSpokesmanWithUserEntity {
	r := make([]*storeSpokesmanGrpc.StoreSpokesmanWithUserEntity, len(list))
	for i, item := range list {
		r[i] = f(item)
	}
	return r
}

/****************************************************************************************/
/*                            store_spokesmanJoins entity of query                      */
/****************************************************************************************/

// ListNormalStoreSpokesmanWithStoresByUserID  获取代言人的代言门店列表
func (s *StoreAPIService) ListNormalStoreSpokesmanWithStoresByUserID(ctx context.Context, req *storeSpokesmanGrpc.ListNormalStoreSpokesmanWithStoresByUserIDRequest) (res *storeSpokesmanGrpc.ListNormalStoreSpokesmanWithStoresByUserIDResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("store_spokesmanImp->ListNormalStoreSpokesmanWithStoresByUserID:%v", req)
	res = &storeSpokesmanGrpc.ListNormalStoreSpokesmanWithStoresByUserIDResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	q := s.dao.Q
	total, err := q.CountNormalStoreSpokesmansByUserID(ctx, req.UserId)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	if total == 0 {
		// 不用继续调用listfunc
		return
	}
	brandSpokesmanWithStores, err := q.ListNormalStoreSpokesmanWithStoresByUserID(ctx, sqlc.ListNormalStoreSpokesmanWithStoresByUserIDParams{
		Limit:  req.Limit,
		Offset: req.Offset,
		UserID: req.UserId,
	})
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.Total = total
	res.StoreSpokesmanWithStores = mapStoreSpokesmanWithStoreEntityToPb(brandSpokesmanWithStores, transformStoreSpokesmanWithStoreEntityToPb)
	return
}

// ListNormalStoreSpokesmanWithUsersByStoreID  获取代言人及其用户信息列表
func (s *StoreAPIService) ListNormalStoreSpokesmanWithUsersByStoreID(ctx context.Context, req *storeSpokesmanGrpc.ListNormalStoreSpokesmanWithUsersByStoreIDRequest) (res *storeSpokesmanGrpc.ListNormalStoreSpokesmanWithUsersByStoreIDResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("store_spokesmanImp->ListNormalStoreSpokesmanWithUsersByStoreID:%v", req)

	res = &storeSpokesmanGrpc.ListNormalStoreSpokesmanWithUsersByStoreIDResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}

	q := s.dao.Q
	ts := sqlc.PBTimestampToGoTime(req.Ts)
	storeID := req.StoreId
	keyword := req.Keyword
	isKeywordEmpty := keyword == ""
	keywordLike := fmt.Sprintf("%%%s%%", keyword)

	total, err := q.CountNormalStoreSpokesmanWithUsersByStoreID(ctx, sqlc.CountNormalStoreSpokesmanWithUsersByStoreIDParams{
		Created:        ts,
		StoreID:        sqlc.NInt64FromInt64(storeID),
		IsKeywordEmpty: isKeywordEmpty,
		Keyword:        keywordLike,
	})
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	if total == 0 {
		// 不用继续调用listfunc
		return
	}

	storeSpokesmanWithUsers, err := q.ListNormalStoreSpokesmanWithUsersByStoreID(ctx, sqlc.ListNormalStoreSpokesmanWithUsersByStoreIDParams{
		Limit:          req.Limit,
		Offset:         req.Offset,
		Created:        ts,
		StoreID:        sqlc.NInt64FromInt64(storeID),
		IsKeywordEmpty: isKeywordEmpty,
		Keyword:        keywordLike,
	})
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.Total = total
	res.StoreSpokesmanWithUsers = mapStoreSpokesmanWithUserEntityToPb(storeSpokesmanWithUsers, transformStoreSpokesmanWithUserEntityToPb)
	return
}
